package com.franklin.ideaplugin.easytesting.registry;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.franklin.ideaplugin.easytesting.rpc.entity.RegistryData;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author Ye Junhui
 * @since 2023/10/8
 */
@RequiredArgsConstructor
public class RegistryServer {

    private final String servicePath;
    private final ThreadPoolExecutor workPool;

    private final ConcurrentMap<String, List<RegistryData>> serviceMap = new ConcurrentHashMap<>();

    public void refresh() {
        File registryDirectory = FileUtil.file(servicePath);
        if (!registryDirectory.isDirectory()) {
            return;
        }
        File[] listFiles = registryDirectory.listFiles();
        List<File> fileList = Lists.newArrayList(listFiles);
        for (List<File> files : Lists.partition(fileList, 20)) {
            workPool.execute(() -> {
                files.stream()
                        .filter(File::isDirectory)
                        .forEach(file -> {
                            String registryPath = file.getAbsolutePath();
                            if (StrUtil.isBlank(registryPath)) {
                                return;
                            }
                            registryPath = registryPath.replace('\\','/');
                            List<RegistryData> registryDataList = loadRegistryData(registryPath);
                            serviceMap.put(registryPath, registryDataList);
                        });
            });
        }
    }

    public List<RegistryData> getRegistryData(String registryPath){
        List<RegistryData> registryDataList = this.serviceMap.get(registryPath);
        if (CollectionUtil.isEmpty(registryDataList)){
            registryDataList = loadRegistryData(registryPath);
            this.serviceMap.put(registryPath,registryDataList);
        }
        return registryDataList;
    }

    @NotNull
    private static List<RegistryData> loadRegistryData(String registryPath) {
        File registryDirectory = FileUtil.file(registryPath);
        if (!registryDirectory.isDirectory()) {
            return Collections.emptyList();
        }
        return Arrays.stream(registryDirectory.listFiles())
                .filter(file -> file.getName().startsWith("etServer_"))
                .map(file -> {
                    String name = file.getName();
                    String[] arr = name.split("_");
                    String appName = arr[1];
                    String port = FileUtil.readString(file.getAbsolutePath(), StandardCharsets.UTF_8);
                    return new RegistryData(appName, port);
                })
                .collect(Collectors.toList());
    }
}
